home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 16
/
Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso
/
Aminet
/
comm
/
term
/
term_source.lha
/
Extras
/
Source
/
term-source.lha
/
CaptureParser.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-20
|
8KB
|
420 lines
/*
** CaptureParser.c
**
** Capture filter parser
**
** Copyright © 1990-1996 by Olaf `Olsen' Barthel
** All Rights Reserved
**
** :ts=4
*/
#ifndef _GLOBAL_H
#include "Global.h"
#endif
/**********************************************************************/
typedef BOOL (* SPECIAL_JUMP)(ParseContext *Context);
typedef BOOL (* ABORT_JUMP)(ParseContext *Context,LONG Char);
STATIC SPECIAL_JUMP *LocalSpecialTable;
STATIC ABORT_JUMP *LocalAbortTable;
/**********************************************************************/
STATIC BOOL
AbortCancel(ParseContext *Context,LONG UnusedChar)
{
Context->pc_InSequence = FALSE;
Context->pc_CharsInBuffer = 0;
Context->pc_ScanStep = 0;
return(FALSE);
}
STATIC BOOL
AbortEsc(ParseContext *Context,LONG c)
{
AbortCancel(Context,c);
Context->pc_InSequence = TRUE;
return(TRUE);
}
STATIC BOOL
LocalParse(ParseContext *Context,LONG c)
{
if(!Context->pc_ScanStep)
{
LONG i;
for(i = 0 ; i < NumCodes ; i++)
{
if(ANSICode[i].FirstChar == c)
{
if(ANSICode[i].ExactSize == 1)
{
Context->pc_CharsInBuffer = Context->pc_ScanStep = 0;
return(FALSE);
}
else
{
Context->pc_ScanStep = i;
Context->pc_SaveBuffer[Context->pc_CharsInBuffer++] = c;
Context->pc_Arnie = ANSICode[i].Terminator;
return(TRUE);
}
}
}
}
else
{
if(Context->pc_CharsInBuffer < MAX_SCAN_SIZE)
{
if(Context->pc_Arnie)
{
LONG i;
for(i = Context->pc_ScanStep ; i < NumCodes ; i++)
{
if(ANSICode[i].FirstChar == Context->pc_SaveBuffer[0])
{
if(Context->pc_Arnie[c])
{
Context->pc_CharsInBuffer = Context->pc_ScanStep = 0;
Context->pc_Arnie = NULL;
return(FALSE);
}
else
{
if(ANSICode[i].Match[c])
{
Context->pc_ScanStep = i;
Context->pc_SaveBuffer[Context->pc_CharsInBuffer++] = c;
return(TRUE);
}
}
}
}
}
else
{
LONG i;
for(i = Context->pc_ScanStep ; i < NumCodes ; i++)
{
if(ANSICode[i].FirstChar == Context->pc_SaveBuffer[0])
{
if(ANSICode[i].LastChar == c || (!ANSICode[i].LastChar && Context->pc_CharsInBuffer == 2 && ANSICode[i].ExactSize == 3)) /* Special case for VT52 */
{
Context->pc_CharsInBuffer = Context->pc_ScanStep = 0;
return(FALSE);
}
else
{
if(ANSICode[i].Match[c])
{
Context->pc_ScanStep = i;
Context->pc_SaveBuffer[Context->pc_CharsInBuffer++] = c;
return(TRUE);
}
}
}
}
}
}
}
Context->pc_CharsInBuffer = Context->pc_ScanStep = 0;
Context->pc_Arnie = NULL;
return(FALSE);
}
STATIC BOOL
AbortCSI(ParseContext *Context,LONG c)
{
AbortCancel(Context,c);
Context->pc_InSequence = TRUE;
return(LocalParse(Context,'['));
}
/**********************************************************************/
STATIC BOOL
SpecialBackspace(ParseContext *Context)
{
if(Context->pc_LineIndex)
Context->pc_LineIndex--;
return(FALSE);
}
STATIC BOOL
SpecialReturn(ParseContext *Context)
{
Context->pc_LineIndex = 0;
return(FALSE);
}
STATIC BOOL
SpecialTab(ParseContext *Context)
{
LONG Index = (Context->pc_LineIndex + 7) & ~8;
if(Index == Context->pc_LineIndex)
Index += 8;
if(Index > Context->pc_LineLen)
memset(&Context->pc_LineBuffer[Context->pc_LineLen],' ',Index - Context->pc_LineLen);
Context->pc_LineIndex = Index;
if(Index > Context->pc_LineLen)
Context->pc_LineLen = Index;
return(FALSE);
}
STATIC BOOL
SpecialEsc(ParseContext *UnusedContext)
{
return(TRUE);
}
STATIC BOOL
SpecialCSI(ParseContext *Context)
{
return(LocalParse(Context,'['));
}
/**********************************************************************/
VOID
CaptureParserExit()
{
FreeVecPooled(LocalSpecialTable);
FreeVecPooled(LocalAbortTable);
LocalSpecialTable = NULL;
LocalAbortTable = NULL;
}
BOOL
CaptureParserInit()
{
if(LocalSpecialTable = (SPECIAL_JUMP *)AllocVecPooled(256 * sizeof(SPECIAL_JUMP),MEMF_ANY | MEMF_CLEAR))
{
if(LocalAbortTable = (ABORT_JUMP *)AllocVecPooled(256 * sizeof(ABORT_JUMP),MEMF_ANY | MEMF_CLEAR))
{
STATIC struct { UBYTE Key; SPECIAL_JUMP Routine; } LocalSpecialKeys[] =
{
'\b', SpecialBackspace,
'\r', SpecialReturn,
'\t', SpecialTab,
27, SpecialEsc,
155, SpecialCSI
};
LONG i;
for(i = 0 ; i < NUM_ELEMENTS(LocalSpecialKeys) ; i++)
LocalSpecialTable[LocalSpecialKeys[i].Key] = LocalSpecialKeys[i].Routine;
for(i = 0 ; i < 256 ; i++)
{
switch(AbortMap[i])
{
case 0:
LocalAbortTable[i] = LocalParse;
break;
case 1:
LocalAbortTable[i] = AbortCancel;
break;
case 2:
LocalAbortTable[i] = AbortEsc;
break;
case 3:
LocalAbortTable[i] = AbortCSI;
break;
}
}
return(TRUE);
}
}
return(FALSE);
}
ParseContext *
CreateParseContext()
{
return((ParseContext *)AllocVecPooled(sizeof(ParseContext),MEMF_ANY | MEMF_CLEAR));
}
/**********************************************************************/
/* CaptureParser(ParseContext *Context,STRPTR Buffer,LONG Size,COPTR OutputRoutine):
*
* This is very similar to what happens in Emulation.c, in fact we're using the
* same data. The basic difference is that no emulation routines are invoked.
* Every single one is skipped, only the special control codes like form feed,
* tab or carriage return survive. Eventually, we end up building single text
* lines that are handed over to the supplied output callback routine. Are we
* having fun?
*/
VOID
CaptureParser(ParseContext *Context,STRPTR Buffer,LONG Size,COPTR OutputRoutine)
{
if(Size > 0)
{
LONG c,Mask;
if(Config->SerialConfig->StripBit8)
Mask = 0x7F;
else
Mask = 0xFF;
if(Context->pc_InSequence)
{
BOOL Result;
do
{
c = *Buffer++ & Mask;
Result = (*LocalAbortTable[c])(Context,c);
}
while(--Size > 0 && Result);
Context->pc_InSequence = Result;
}
if(Size > 0)
{
LONG BufferWidth = Config->CaptureConfig->BufferWidth - 1;
if(Config->TerminalConfig->FontMode == FONT_STANDARD)
{
do
{
c = (*Buffer++) & Mask;
if(Context->pc_InSequence)
Context->pc_InSequence = (*LocalAbortTable[c])(Context,c);
else
{
if(LocalSpecialTable[c])
Context->pc_InSequence = (*LocalSpecialTable[c])(Context);
else
{
if(c == '\n' || c == '\f' || c == '\v')
{
(*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
Context->pc_LineIndex = Context->pc_LineLen = 0;
}
else
{
if(IsGlyph[c])
{
Context->pc_LineBuffer[Context->pc_LineIndex++] = c;
if(Context->pc_LineIndex > Context->pc_LineLen)
Context->pc_LineLen = Context->pc_LineIndex;
if(Context->pc_LineLen > BufferWidth)
{
(*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
Context->pc_LineIndex = Context->pc_LineLen = 0;
}
}
}
}
}
}
while(--Size > 0);
}
else
{
do
{
c = (*Buffer++) & Mask;
if(Context->pc_InSequence)
Context->pc_InSequence = (*LocalAbortTable[c])(Context,c);
else
{
if(LocalSpecialTable[c])
Context->pc_InSequence = (*LocalSpecialTable[c])(Context);
else
{
if(c == '\n' || c == '\f' || c == '\v')
{
(*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
Context->pc_LineIndex = Context->pc_LineLen = 0;
}
else
{
if(c)
{
Context->pc_LineBuffer[Context->pc_LineIndex++] = c;
if(Context->pc_LineIndex > Context->pc_LineLen)
Context->pc_LineLen = Context->pc_LineIndex;
if(Context->pc_LineLen > BufferWidth)
{
(*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
Context->pc_LineIndex = Context->pc_LineLen = 0;
}
}
}
}
}
}
while(--Size > 0);
}
}
}
}